package com.adcc.loadsheet.monitor.entity;

import com.adcc.loadsheet.monitor.util.AlarmEnum;
import com.adcc.loadsheet.monitor.util.Constant;
import com.adcc.loadsheet.monitor.util.StringUtil;

import java.util.HashSet;
import java.util.Set;

public class MQMonitor extends BaseEntity implements Cloneable{

    // IP地址
    private String ip;

    // 上行TOPIC名称
    private String uplinkTopic;

    // 上行TOPIC消费者数量
    private long uplinkTopicConsumerNum;

    // 上行TOPIC入消息总数
    private long unlinkTopicEnqueued;

    // 下行TOPIC名称
    private String downlinkTopic;

    // 下行TOPIC消费者数量
    private long downlinkTopicConsumerNum;

    // 下行TOPIC入消息总数
    private long downlinkTopicEnqueued;

    // 总体状态
    private MonitorStatus status = MonitorStatus.ABNORMAL;

    // 异常状态码(0：正常，1：异常，2：告警)
    private String errorCode = "0";

    // 异常原因：XXX IS DOWN,XXX IS DOWN
    private String errorReason = "";

    // 本模块异常的节点
    private Set<String> alarmContent = new HashSet<>();

    // 本模块正常的节点（用于判断告警确认后，部分节点正常后又异常需要重新告警）
    private Set<String> unAlarmContent = new HashSet<>();

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getUplinkTopic() {
        return uplinkTopic;
    }

    public void setUplinkTopic(String uplinkTopic) {
        this.uplinkTopic = uplinkTopic;
    }

    public long getUplinkTopicConsumerNum() {
        return uplinkTopicConsumerNum;
    }

    public void setUplinkTopicConsumerNum(long uplinkTopicConsumerNum) {
        this.uplinkTopicConsumerNum = uplinkTopicConsumerNum;
    }

    public long getUnlinkTopicEnqueued() {
        return unlinkTopicEnqueued;
    }

    public void setUnlinkTopicEnqueued(long unlinkTopicEnqueued) {
        this.unlinkTopicEnqueued = unlinkTopicEnqueued;
    }

    public String getDownlinkTopic() {
        return downlinkTopic;
    }

    public void setDownlinkTopic(String downlinkTopic) {
        this.downlinkTopic = downlinkTopic;
    }

    public long getDownlinkTopicConsumerNum() {
        return downlinkTopicConsumerNum;
    }

    public void setDownlinkTopicConsumerNum(long downlinkTopicConsumerNum) {
        this.downlinkTopicConsumerNum = downlinkTopicConsumerNum;
    }

    public long getDownlinkTopicEnqueued() {
        return downlinkTopicEnqueued;
    }

    public void setDownlinkTopicEnqueued(long downlinkTopicEnqueued) {
        this.downlinkTopicEnqueued = downlinkTopicEnqueued;
    }

    public MonitorStatus getStatus() {
        return status;
    }

    public void setStatus(MonitorStatus status) {
        this.status = status;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorReason() {
        return errorReason;
    }

    public void setErrorReason(String errorReason) {
        this.errorReason = errorReason;
    }

    public Set<String> getAlarmContent() {
        return alarmContent;
    }

    public void setAlarmContent(Set<String> alarmContent) {
        this.alarmContent = alarmContent;
    }

    public Set<String> getUnAlarmContent() {
        return unAlarmContent;
    }

    public void setUnAlarmContent(Set<String> unAlarmContent) {
        this.unAlarmContent = unAlarmContent;
    }

    @Override
    public String toXML() throws Exception {
        return null;
    }

    @Override
    public String toJSON() throws Exception {
        return null;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        MQMonitor mq = new MQMonitor();
        mq.setIp(ip);
        mq.setUplinkTopic(uplinkTopic);
        mq.setUplinkTopicConsumerNum(uplinkTopicConsumerNum);
        mq.setUnlinkTopicEnqueued(unlinkTopicEnqueued);
        mq.setDownlinkTopic(downlinkTopic);
        mq.setDownlinkTopicConsumerNum(downlinkTopicConsumerNum);
        mq.setDownlinkTopicEnqueued(downlinkTopicEnqueued);
        mq.setStatus(status);
        mq.setErrorCode(errorCode);
        mq.setErrorReason(errorReason);
        mq.setAlarmContent(alarmContent);
        mq.setUnAlarmContent(unAlarmContent);
        return mq;
    }

    /**
     * 异常状态码
     */
    public void buildErrorCode() {
        StringBuilder sb = new StringBuilder();
        char[] states = new char[1];
        states[0] = status == MonitorStatus.NORMAL ? '0' : status == MonitorStatus.ABNORMAL ? '1' : '2';
        for(char c : states){
            sb.append(c);
        }
        this.errorCode = sb.toString();

        // [2024-6-01：张丽娟：增加声音和弹窗告警的功能，系统支持对指定告警项进行声音和弹窗告警忽略的功能: 根据状态码获取正常节点和异常节点信息]
        // 本模块异常的节点
        Set<String> alarmContent = new HashSet<>();
        // 本模块正常的节点（用于判断告警确认后，部分节点正常后又异常需要重新告警）
        Set<String> unAlarmContent = new HashSet<>();
        // 保存到数据库的异常信息
        StringBuilder errorReasonBuilder = new StringBuilder();

        AlarmEnum enumMQ = AlarmEnum.MQ_MQ;
        if (states[0] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumMQ.getMysqlLogName()));
            alarmContent.add(enumMQ.getItem());
        }else if(states[0] == '2'){
            errorReasonBuilder.append(String.format(Constant.LOG_WARN, enumMQ.getMysqlLogName()));
            alarmContent.add(enumMQ.getItem());
        }else{
            unAlarmContent.add(enumMQ.getItem());
        }

        this.alarmContent = alarmContent;
        this.unAlarmContent = unAlarmContent;
        this.errorReason = StringUtil.stringBuilderToString(errorReasonBuilder);
    }

    /**
     * 告警升级，需要重新告警，即由一般变严重
     * （告警降级不需要重新告警，即由严重到一般）
     * 注：mq没有WARNING状态赋值，这里不会被执行到
     */
    public static Set<String> getReAlarmContents(MonitorStatus lastStatus, MonitorStatus curStatus) {
        // 告警升级，需要重新告警，即由一般变严重（告警降级不需要重新告警，即由严重到一般）
        Set<String> reAlertContent = new HashSet<>();
        // 上一次为一般告警，本次为严重告警
        if(lastStatus == MonitorStatus.WARNING && curStatus == MonitorStatus.ABNORMAL){
            AlarmEnum enumMQ = AlarmEnum.MQ_MQ;
            reAlertContent.add(enumMQ.getItem());
        }
        return reAlertContent;
    }
}
